package com.zx.idc.backend.gui.api.management.basicdata.report.impl;

import com.zx.idc.backend.gui.api.commom.entity.UploadModel;
import com.zx.idc.backend.gui.api.commom.template.NIdcFtpTemplate;
import com.zx.idc.backend.gui.api.management.basicdata.BaseIdcBasicDataService;
import com.zx.idc.backend.gui.api.management.basicdata.common.BasicDataDefaultInstance;
import com.zx.idc.backend.gui.api.management.basicdata.report.IdcBasicDataReportService;
import com.zx.idc.backend.gui.api.management.basicdata.report.IdcBasicDataUtil;
import com.zx.idc.common.attributes.FTPReportDataTypeEnum;
import com.zx.idc.common.attributes.NetCommunicationFileTypeEnum;
import com.zx.idc.common.attributes.SchemaFileNameEnum;
import com.zx.idc.common.exception.GlobalException;
import com.zx.idc.ds.base.cus.entity.BaseCustomer;
import com.zx.idc.ds.base.cus.service.IBaseCustomerService;
import com.zx.idc.ds.base.cus.service.IBaseServiceInfoService;
import com.zx.idc.ds.base.cus.vo.BaseCustomerVo;
import com.zx.idc.ds.base.house.entity.*;
import com.zx.idc.ds.base.house.service.*;
import com.zx.idc.ds.base.ip.entity.BaseIpAddressInfo;
import com.zx.idc.ds.base.ip.service.IBaseIpAddressInfoService;
import com.zx.idc.ds.base.oper.entity.BaseOperCompany;
import com.zx.idc.ds.base.oper.service.IBaseOperCompanyService;
import com.zx.idc.ds.base.serve.entity.BaseServiceDomain;
import com.zx.idc.ds.base.serve.service.IBaseServiceDomainService;
import com.zx.idc.ds.base.server.entity.BaseServerInfo;
import com.zx.idc.ds.base.server.service.IBaseServerInfoService;
import com.zx.idc.ds.common.constant.DataFeatureConstant;
import com.zx.idc.ds.common.constant.ReportStatusConstant;
import com.zx.idc.xml.entity.basedata.BasicInfo;
import com.zx.idc.xml.entity.basedata.UpdateInfo;
import com.zx.idc.xml.entity.basedata.basic.EmergencyContact;
import com.zx.idc.xml.entity.basedata.basic.HouseInfo;
import com.zx.idc.xml.entity.basedata.basic.IdcOfficer;
import com.zx.idc.xml.entity.basedata.basic.UserInfo;
import com.zx.idc.xml.entity.basedata.basic.userinfo.*;
import com.zx.idc.xml.entity.basedata.delete.DeleteData;
import com.zx.idc.xml.entity.basedata.delete.DeleteInfo;
import com.zx.idc.xml.entity.basedata.delete.House;
import com.zx.idc.xml.entity.basedata.delete.User;
import com.zx.idc.xml.entity.basedata.newinfo.NewInfo;
import com.zx.idc.xml.entity.basedata.updateinfo.UpdateData;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author rxliuli
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class IdcBasicDataReportServiceImpl implements IdcBasicDataReportService {
    private static final Logger LOG = LoggerFactory.getLogger(IdcBasicDataReportServiceImpl.class);
    @Autowired
    protected IBaseOperCompanyService baseOperCompanyService;
    @Autowired
    protected IBaseHouseInfoService baseHouseInfoService;
    @Autowired
    protected IBaseCustomerService baseCustomerService;
    @Autowired
    protected IBaseHouseOfficerService baseHouseOfficerService;
    @Autowired
    protected IBaseHouseLinkInfoService baseHouseLinkInfoService;
    @Autowired
    protected IBaseIpAddressInfoService baseIpAddressInfoService;
    @Autowired
    protected IBaseIdcHouseAreaService baseIdcHouseAreaService;
    @Autowired
    protected IBaseFrameInfoService baseFrameInfoService;
    @Autowired
    protected IBaseHousesHoldInfoService baseHousesHoldInfoService;
    @Autowired
    protected IBaseIpTransInfoService baseIpTransInfoService;
    @Autowired
    protected IBaseServerInfoService baseServerInfoService;
    @Autowired
    protected IBaseServiceDomainService baseServiceDomainService;
    @Autowired
    protected IdcBasicDataUtil idcBasicDataUtil;
    @Autowired
    private NIdcFtpTemplate nIdcFtpTemplate;
    @Autowired
    private IBaseServiceInfoService baseServiceInfoService;
    @Autowired
    private BasicDataDefaultInstance basicDataDefaultInstance;
    @Autowired
    private BaseIdcBasicDataService baseIdcBasicDataService;

    @Override
    public void activeReporting() {
         /*
        - 基础数据上报信息 basicInfo -> BaseOperCompany
          - 新增信息 newInfo -> BaseOperCompany
            - 网络信息安全责任人 idcOfficer -> BaseHouseOfficer
            - 应急联系人信息 EmergencyContact -> BaseHouseOfficer
            - 新增机房数据 houseInfo -> BaseHouseInfo
            - 新增用户数据 userInfo -> BaseCustomer
          - 修改信息 updateInfo -> BaseOperCompany
            - 网络信息安全责任人信息 idcOfficer -> BaseHouseOfficer
            - 应急联系人信息 emergencyContact -> BaseHouseOfficer
            - 更新数据 updateData -> BaseHouseInfo/BaseCustomer
          - 删除信息 deleteInfo -> BaseOperCompany
            - 删除的机房数据 house -> BaseHouseInfo
            - 删除的用户数据 user -> BaseCustomer
         */
        // 获取所有经营单位（不包含删除的）(目前只需要删除上报）
        List<BaseOperCompany> baseOperCompanies = baseOperCompanyService.selectList(new BaseOperCompany());
        baseOperCompanies.forEach(boc -> {
//                //新增上报
//                NewInfo newInfo = getNewInfo(boc);
//                if (newInfo != null) {
//                    basicInfoReport(new BasicInfo(newInfo, null, null, LocalDateTime.now()));
//                    LOG.info("基础数据整体 新增 上报任务 执行成功");
//                }
//                //更新上报
//                UpdateInfo updateInfo = getUpdateInfo(boc);
//                if (updateInfo != null) {
//                    basicInfoReport(new BasicInfo(null, updateInfo, null, LocalDateTime.now()));
//                    LOG.info("基础数据整体 更新 上报任务 执行成功");
//                }
                //删除上报
                DeleteInfo deleteInfo = getDeleteInfo(boc);
                if (deleteInfo != null) {
                    basicInfoReport(new BasicInfo(null, null, deleteInfo, LocalDateTime.now()));
                    LOG.info("基础数据整体 删除 上报任务 执行成功");
                }
            }
        );
        LOG.info("基础数据整体 上报任务 执行成功");
    }

    private void basicInfoReport(BasicInfo basicInfo) {
        baseIdcBasicDataService.update(basicInfo, ReportStatusConstant.REPORTING);
        nIdcFtpTemplate.uploadXMLFile(new UploadModel<>(
            basicInfo,
            SchemaFileNameEnum.BASE_DATA_REPORT,
            FTPReportDataTypeEnum.FTP_BASE_DATA,
            NetCommunicationFileTypeEnum.BASE_DATA
        ));
    }

    @Override
    public BasicInfo operCompanyAddReport(String idcId) {
        final NewInfo info = basicDataDefaultInstance.getNewInfo(idcId);
        final BaseOperCompany baseOperCompany = baseOperCompanyService.selectById(idcId);
        info.setIdcId(baseOperCompany.getIdcId());
        info.setIdcName(baseOperCompany.getOperName());
        info.setCorp(baseOperCompany.getCompanyCorporation());
        info.setIdcZip(baseOperCompany.getZipCode());
        info.setIdcAdd(baseOperCompany.getAddress());
//        info.setHouseCount((long) baseHouseInfoService.selectCount(new BaseHouseInfo().setIdcId(idcId)));
        final BaseHouseOfficer emergencyContact = baseHouseOfficerService.selectById(baseOperCompany.getEmergencyContact());
        info.setEmergencyContact(emergencyContact != null ? officerToEmergencyContact(emergencyContact) : null);
        final BaseHouseOfficer idcOfficer = baseHouseOfficerService.selectById(baseOperCompany.getSecurityOwner());
        info.setIdcOfficer(idcOfficer != null ? officerToIdcOfficer(idcOfficer) : null);
        final BasicInfo result = basicDataDefaultInstance.getBasicInfo();


        result.setNewInfo(info);
        return result;
    }

    @Override
    public BasicInfo operCompanyUpdateReport(String idcId) {
        final UpdateInfo info = basicDataDefaultInstance.getUpdateInfo(idcId);
        final BaseOperCompany baseOperCompany = baseOperCompanyService.selectById(idcId);
        info.setIdcName(baseOperCompany.getOperName());
        info.setCorp(baseOperCompany.getCompanyCorporation());
        info.setIdcZip(baseOperCompany.getZipCode());
        info.setIdcAdd(baseOperCompany.getAddress());
        final BaseHouseOfficer emergencyContact = baseHouseOfficerService.selectById(baseOperCompany.getEmergencyContact());
        info.setEmergencyContact(officerToEmergencyContact(emergencyContact));
        final BaseHouseOfficer idcOfficer = baseHouseOfficerService.selectById(baseOperCompany.getSecurityOwner());
        info.setIdcOfficer(officerToIdcOfficer(idcOfficer));
        final BasicInfo result = basicDataDefaultInstance.getBasicInfo();
        result.setUpdateInfo(info);
        return result;
    }

    @Override
    public BasicInfo operCompanyDeleteReport(String idcId) {
        final DeleteInfo info = new DeleteInfo();
        info.setIdcId(idcId);
        final BasicInfo result = new BasicInfo();
        result.setDeleteInfo(info);
        result.setTimeStamp(LocalDateTime.now());
        return result;
    }

    @Override
    public BasicInfo baseHouseInfoAddReport(Long id) {
        final BaseHouseInfo baseHouseInfo = baseHouseInfoService.selectById(id);
        if (baseHouseInfo.getReportStatus() == ReportStatusConstant.REPORTING) {
            throw new GlobalException("机房ID为 " + id + " 已经处于上报中,请刷新页面查看");
        }
        final String idcId = baseHouseInfo.getIdcId();
        BaseOperCompany baseOperCompany = baseOperCompanyService.selectOne(new BaseOperCompany().setIdcId(idcId));
        if (baseOperCompany.getDataFeature() == DataFeatureConstant.NEW && (baseOperCompany.getReportStatus() == ReportStatusConstant.NOT_REPORTED || baseOperCompany.getReportStatus() == ReportStatusConstant.REPORTING)) {
            throw new GlobalException("该机房所属经营单位 未完成上报");
        }
        final NewInfo newInfo = new NewInfo();
        newInfo.getHouseInfo().add(getHouseInfo(baseHouseInfo));
        final BasicInfo result = new BasicInfo();
        newInfo.setIdcId(idcId)
            .setIdcName(baseOperCompany.getOperName())
            .setIdcAdd(baseOperCompany.getAddress())
            .setIdcZip(baseOperCompany.getZipCode())
            .setCorp(baseOperCompany.getCompanyCorporation());

        //网络信息安全责任人信息
        final BaseHouseOfficer securityOwner = baseHouseOfficerService.selectById(baseOperCompany.getSecurityOwner());
        newInfo.setIdcOfficer(securityOwner != null ? officerToIdcOfficer(securityOwner) : null);
        //紧急联系人
        final BaseHouseOfficer emergencyContact = baseHouseOfficerService.selectById(baseOperCompany.getEmergencyContact());
        newInfo.setEmergencyContact(emergencyContact != null ? officerToEmergencyContact(emergencyContact) : null);


        result.setNewInfo(newInfo);
        result.setTimeStamp(LocalDateTime.now());
        return result;
    }

    @Override
    public BasicInfo baseHouseInfoUpdateReport(Long id) {
        final BaseHouseInfo baseHouseInfo = baseHouseInfoService.selectById(id);
        if (baseHouseInfo.getReportStatus() == ReportStatusConstant.REPORTING) {
            throw new GlobalException("机房ID为 " + id + " 已经处于上报中,请刷新页面查看");
        }
        final UpdateInfo updateInfo = new UpdateInfo()
            .setUpdateData(
                new UpdateData()
                    .setHouseInfo(
                        Lists.newArrayList(
                            getHouseInfo(baseHouseInfo)
                        )
                    )
            )
            .setIdcId(baseHouseInfo.getIdcId());

        return new BasicInfo()
            .setUpdateInfo(updateInfo)
            .setTimeStamp(LocalDateTime.now());
    }

    /**
     * 获取HouseInfo上报数据
     *
     * @param baseHouseInfo 机房信息
     * @return 机房上报数据
     */
    private HouseInfo getHouseInfo(BaseHouseInfo baseHouseInfo) {
        //所属机房区域
        final List<BaseIdcHouseArea> baseIdcHouseAreaList = baseIdcBasicDataService.queryBaseIdcHouseAreaList(Collections.singletonList(baseHouseInfo));
        //机架信息
        final List<BaseFrameInfo> baseFrameInfoList = baseIdcBasicDataService.queryBaseFrameInfoList(baseIdcHouseAreaList);
        if (baseFrameInfoList.size() == 0) {
            throw new GlobalException("缺少该机房对应的 机架 信息");
        }
        //机房安全负责人
        final BaseHouseOfficer baseHouseOfficer = baseHouseOfficerService.selectById(baseHouseInfo.getHouseOfficer());
        //链路信息
        final List<BaseHouseLinkInfo> baseHouseLinkInfos = baseHouseLinkInfoService.selectList(new BaseHouseLinkInfo().setHouseId(baseHouseInfo.getId()));
        //IP地址信息
        final List<BaseIpAddressInfo> baseIpAddressInfos = baseIpAddressInfoService.selectList(new BaseIpAddressInfo().setHouseId(baseHouseInfo.getId()));
        if (baseIpAddressInfos.size() == 0) {
            throw new GlobalException("缺少该机房对应的 IP地址 信息");
        }
        return IdcBasicDataUtil.convertHouseInfo(baseHouseInfo, baseHouseOfficer, baseHouseLinkInfos, baseIpAddressInfos, baseFrameInfoList);
    }

    @Override
    public BasicInfo baseHouseInfoDeleteReport(Long id) {
        final House house = new House();
        house.setHouseId(id);
        final DeleteInfo deleteInfo = new DeleteInfo();
        deleteInfo.getDeleteData().getHouse().add(house);
        final BasicInfo result = new BasicInfo();
        result.setDeleteInfo(deleteInfo);
        return result;
    }

    @Override
    public BasicInfo baseCustomerAddReport(Long id) {
        BaseCustomer baseCustomer = baseCustomerService.selectById(id);
        if (baseCustomer.getReportStatus() == ReportStatusConstant.REPORTING) {
            throw new GlobalException("客户ID为 " + id + " 已经处于上报中,请刷新页面查看");
        }
        BaseOperCompany baseOperCompany = baseOperCompanyService.selectOne(new BaseOperCompany().setIdcId(baseCustomer.getIdcId()));
        if (baseOperCompany.getDataFeature() == DataFeatureConstant.NEW && (baseOperCompany.getReportStatus() == ReportStatusConstant.NOT_REPORTED || baseOperCompany.getReportStatus() == ReportStatusConstant.REPORTING)) {
            throw new GlobalException("该客户所属经营单位 未完成上报，请稍后重试");
        }
        Long frameInfoId = baseHousesHoldInfoService.selectOne(new BaseHousesHoldInfo().setCustomerId(id)).getFrameInfoId();
        Long houseId = baseFrameInfoService.selectHouseId(frameInfoId);
        BaseHouseInfo baseHouseInfo = baseHouseInfoService.selectOne(new BaseHouseInfo().setId(houseId));
        if (baseHouseInfo.getDataFeature() == DataFeatureConstant.NEW && (baseHouseInfo.getReportStatus() == ReportStatusConstant.NOT_REPORTED || baseHouseInfo.getReportStatus() == ReportStatusConstant.REPORTING)) {
            throw new GlobalException("该客户占用机房 未完成上报，请稍后重试");
        }
        final UserInfo userInfo = getUserInfo(id);
        final NewInfo newInfo = new NewInfo();
        newInfo.getUserInfo().add(userInfo);
        newInfo.setIdcId(baseCustomer.getIdcId())
            .setIdcName(baseOperCompany.getOperName())
            .setIdcAdd(baseOperCompany.getAddress())
            .setIdcZip(baseOperCompany.getZipCode())
            .setCorp(baseOperCompany.getCompanyCorporation());
        //网络信息安全责任人信息
        final BaseHouseOfficer securityOwner = baseHouseOfficerService.selectById(baseOperCompany.getSecurityOwner());
        newInfo.setIdcOfficer(securityOwner != null ? officerToIdcOfficer(securityOwner) : null);
        //紧急联系人
        final BaseHouseOfficer emergencyContact = baseHouseOfficerService.selectById(baseOperCompany.getEmergencyContact());
        newInfo.setEmergencyContact(emergencyContact != null ? officerToEmergencyContact(emergencyContact) : null);

        final BasicInfo result = new BasicInfo();
        result.setNewInfo(newInfo);
        result.setTimeStamp(LocalDateTime.now());
        return result;
    }

    @Override
    public BasicInfo baseCustomerUpdateReport(Long id) {
        BaseCustomer baseCustomer = baseCustomerService.selectById(id);
        if (baseCustomer.getReportStatus() == ReportStatusConstant.REPORTING) {
            throw new GlobalException("客户ID为 " + id + " 已经处于上报中,请刷新页面查看");
        }
        final UserInfo userInfo = getUserInfo(id);
        final UpdateInfo updateInfo = new UpdateInfo();
        UpdateData updateData = new UpdateData();
        updateInfo.setUpdateData(updateData);
        updateInfo.getUpdateData().getUserInfo().add(userInfo);
        updateInfo.setIdcId(baseCustomer.getIdcId());
        final BasicInfo result = new BasicInfo();
        result.setUpdateInfo(updateInfo);
        result.setTimeStamp(LocalDateTime.now());
        return result;
    }

    @Override
    public BasicInfo baseCustomerDeleteReport(Long id) {
        final User user = new User();
        user.setUserId(id);
        final DeleteInfo deleteInfo = new DeleteInfo();
        deleteInfo.getDeleteData().getUser().add(user);
        final BasicInfo result = new BasicInfo();
        result.setDeleteInfo(deleteInfo);
        result.setTimeStamp(LocalDateTime.now());
        return result;
    }

    @Override
    public BasicInfo baseIpAddressInfoAddReport(Long id) {
        final HouseInfo houseInfo = new HouseInfo();
        BaseIpAddressInfo baseIpAddressInfo = baseIpAddressInfoService.selectById(id);
        Long houseId = baseIpAddressInfo.getHouseId();
        houseInfo.getIpSegInfo().add(IdcBasicDataUtil.getIpSegInfo(baseIpAddressInfoService.selectById(id)));
        final NewInfo info = new NewInfo();
        info.getHouseInfo().add(houseInfo);
        final BaseHouseInfo baseHouseInfo = baseHouseInfoService.selectById(houseId);
        final String idcId = baseHouseInfo.getIdcId();
        BaseOperCompany baseOperCompany = baseOperCompanyService.selectOne(new BaseOperCompany().setIdcId(idcId));
        final BasicInfo result = new BasicInfo();
        info.setIdcId(idcId)
            .setIdcName(baseOperCompany.getOperName())
            .setIdcAdd(baseOperCompany.getAddress())
            .setIdcZip(baseOperCompany.getZipCode())
            .setCorp(baseOperCompany.getCompanyCorporation());

        //网络信息安全责任人信息
        final BaseHouseOfficer securityOwner = baseHouseOfficerService.selectById(baseOperCompany.getSecurityOwner());
        info.setIdcOfficer(securityOwner != null ? officerToIdcOfficer(securityOwner) : null);
        //紧急联系人
        final BaseHouseOfficer emergencyContact = baseHouseOfficerService.selectById(baseOperCompany.getEmergencyContact());
        info.setEmergencyContact(emergencyContact != null ? officerToEmergencyContact(emergencyContact) : null);

        result.setNewInfo(info);
        return result;
    }

    @Override
    public BasicInfo baseIpAddressInfoUpdateReport(Long id) {
        final HouseInfo houseInfo = new HouseInfo();
        houseInfo.getIpSegInfo().add(IdcBasicDataUtil.getIpSegInfo(baseIpAddressInfoService.selectById(id)));
        final UpdateInfo info = new UpdateInfo();
        info.getUpdateData().getHouseInfo().add(houseInfo);
        final BasicInfo result = new BasicInfo();
        result.setUpdateInfo(info);
        return result;
    }

    @Override
    public BasicInfo baseIpAddressInfoDeleteReport(Long id) {
        final House house = new House();
        house.setIpSegId(id);
        final DeleteInfo info = new DeleteInfo();
        info.getDeleteData().getHouse().add(house);
        final BasicInfo result = new BasicInfo();
        result.setDeleteInfo(info);
        return result;
    }

    @Override
    public BasicInfo baseHouseOfficerAdd(Long id) {
        // TODO 这里需要完善
        return null;
    }

    @Override
    public BasicInfo baseHouseOfficerUpdate(Long id) {
        // TODO 这里需要完善
        return null;
    }

    @Override
    public BasicInfo baseHouseOfficerDelete(Long idcId) {
        // TODO 这里需要完善
        return null;
    }

    private UserInfo getUserInfo(Long id) {
        final BaseCustomerVo baseCustomer = baseCustomerService.getForAllBaseHousesHoldInfo(id);
        //提供互联网应用服务的用户信息所需要的服务信息
        final List<HousesHoldInfo> housesHoldInfoList = baseCustomer.getUserType() == BaseCustomer.USER_TYPE_SERVICE ? baseCustomer.getBaseHousesHoldInfoList().stream().map(bhhi -> {
            Long houseId = baseFrameInfoService.selectHouseId(bhhi.getFrameInfoId());
            List<IpTrans> ipTransList = baseIpTransInfoService.selectList(new BaseIpTransInfo().setHoldId(bhhi.getId())).stream().map(itf -> {
                IpTrans ipTrans = new IpTrans(new InternetIp(itf.getInternetStartIp(), itf.getInternetEndIp()), null);
                if (StringUtils.isEmpty(itf.getPrivateStartIp()) || StringUtils.isEmpty(itf.getPrivateEndIp())) {
                    return ipTrans;
                }
                NetIp netIp = new NetIp(itf.getPrivateStartIp(), itf.getPrivateEndIp());
                ipTrans.setNetIp(netIp);
                return ipTrans;
            }).collect(Collectors.toList());
            VirtualServer virtualServer = null;
            if (bhhi.getVirtualHostName() != null && bhhi.getVirtualHostType() != null && bhhi.getVirtualHostAddress() != null && bhhi.getVirtualHostManagement() != null) {
                virtualServer = new VirtualServer(
                    bhhi.getVirtualHostName(),
                    bhhi.getVirtualHostState(),
                    bhhi.getVirtualHostType(),
                    bhhi.getVirtualHostAddress(),
                    bhhi.getVirtualHostManagement()
                );
            }
            return new HousesHoldInfo(
                bhhi.getId(),
                houseId,
                bhhi.getDistributeTime(),
                bhhi.getBandWidth(),
                ipTransList,
                bhhi.getFrameInfoId(),
                virtualServer
            );
        }).collect(Collectors.toList()) : null;

        final List<ServiceInfo> serviceInfoList = baseCustomer.getUserType() == BaseCustomer.USER_TYPE_SERVICE ? baseCustomer.getBaseServiceInfoList().stream().map(bsi -> {
            List<HousesHoldInfo> hhiList = housesHoldInfoList != null ? housesHoldInfoList.stream().filter(hhi -> hhi.getHhId() == bsi.getHoldId()).collect(Collectors.toList()) : null;
            List<Domain> domain = baseCustomer.getBaseServiceDomainList().stream()
                .filter(sd -> sd.getServiceId().equals(bsi.getId()))
                .map(bsd -> new Domain(bsd.getId(), bsd.getDomain()))
                .collect(Collectors.toList());
            String[] sc = bsi.getServiceContent().split(",");
            List<Integer> serviceContent = new ArrayList<Integer>();
            for (String s : sc) {
                serviceContent.add(Integer.valueOf(s));
            }
            return new ServiceInfo(
                bsi.getId(),
                serviceContent,
                bsi.getRegType(),
                bsi.getRegId(),
                bsi.getSetMode(),
                bsi.getBusinessType(),
                domain,
                hhiList
            );
        }).collect(Collectors.toList()) : null;

        //其他用户
        final List<HouseHoldInfo> houseHoldInfoList = baseCustomer.getUserType() == BaseCustomer.USER_TYPE_OTHER ? baseCustomer.getBaseHousesHoldInfoList().stream().map(bhhi -> {
            Long houseId = baseFrameInfoService.selectHouseId(bhhi.getFrameInfoId());
            List<IpSeg> ipSegList = baseIpTransInfoService.selectList(new BaseIpTransInfo().setHoldId(bhhi.getId())).stream().map(itf -> new IpSeg(
                itf.getId(), itf.getInternetStartIp(), itf.getInternetEndIp()
            )).collect(Collectors.toList());
            return new HouseHoldInfo(
                bhhi.getId(),
                houseId,
                bhhi.getBandWidth(),
                bhhi.getDistributeTime(),
                ipSegList
            );
        }).collect(Collectors.toList()) : null;

        return new UserInfo(baseCustomer.getId(), baseCustomer.getUserType(), new Info(
            baseCustomer.getUnitName(),
            baseCustomer.getUnitNature(),
            baseCustomer.getIdType(),
            baseCustomer.getIdNumber(),
            officerToOfficer(baseHouseOfficerService.selectById(baseCustomer.getOfficer())),
            baseCustomer.getAddress(),
            baseCustomer.getZipCode(),
            baseCustomer.getServiceRegTime(),
            serviceInfoList,
            houseHoldInfoList,
            baseCustomer.getRegisterTime()
        ));
    }

    private EmergencyContact officerToEmergencyContact(BaseHouseOfficer baseHouseOfficer) {
        return new EmergencyContact(baseHouseOfficer.getName(), baseHouseOfficer.getIdType(), baseHouseOfficer.getIdNumber(), baseHouseOfficer.getTel(), baseHouseOfficer.getMobile(), baseHouseOfficer.getEmail());
    }

    private IdcOfficer officerToIdcOfficer(BaseHouseOfficer baseHouseOfficer) {
        return new IdcOfficer(baseHouseOfficer.getName(), baseHouseOfficer.getIdType(), baseHouseOfficer.getIdNumber(), baseHouseOfficer.getTel(), baseHouseOfficer.getMobile(), baseHouseOfficer.getEmail());
    }

    private Officer officerToOfficer(BaseHouseOfficer baseHouseOfficer) {
        return new Officer(baseHouseOfficer.getName(), baseHouseOfficer.getIdType(), baseHouseOfficer.getIdNumber().toString(), baseHouseOfficer.getTel(), baseHouseOfficer.getMobile(), baseHouseOfficer.getEmail());
    }

    /**
     * 构建上报信息实体 DeleteInfo
     *
     * @param deleteBaseOperCompany
     * @return
     */
    private DeleteInfo getDeleteInfo(BaseOperCompany deleteBaseOperCompany) {
        final DeleteInfo deleteInfo = new DeleteInfo();
        deleteInfo.setIdcId(deleteBaseOperCompany.getIdcId());
        if (deleteBaseOperCompany.getDataFeature() == DataFeatureConstant.DELETE && deleteBaseOperCompany.getReportStatus() == ReportStatusConstant.NOT_REPORTED) {
            return deleteInfo;
        }
        deleteInfo.setDeleteData(new DeleteData());
        //未上报的机房数据
        final List<BaseHouseInfo> baseHouseInfoList = baseHouseInfoService.selectListForDelReport(new BaseHouseInfo().setIdcId(deleteBaseOperCompany.getIdcId()));
        //获取未上报的机房删除记录
        baseHouseInfoList.stream()
            .filter(bhi -> bhi.getDataFeature() == DataFeatureConstant.DELETE && bhi.getReportStatus() == ReportStatusConstant.NOT_REPORTED)
            .forEach(bhi -> deleteInfo.getDeleteData().getHouse().add(new House(bhi.getId(), null, null)));

        baseHouseInfoList.stream()
            .filter(bhi -> bhi.getDataFeature() != DataFeatureConstant.DELETE)
            .forEach(bhi -> {
                //删除的链路信息
                baseHouseLinkInfoService.selectListForDelReport(new BaseHouseLinkInfo().setHouseId(bhi.getId())
                    .setDataFeature(DataFeatureConstant.DELETE).setReportStatus(ReportStatusConstant.NOT_REPORTED))
                    .forEach(gateway -> deleteInfo.getDeleteData().getHouse().add(new House(bhi.getId(), gateway.getId(), null)));
                //删除的ip 地址段信息
                baseIpAddressInfoService.selectListForDelReport(new BaseIpAddressInfo().setHouseId(bhi.getId())
                    .setDataFeature(DataFeatureConstant.DELETE).setReportStatus(ReportStatusConstant.NOT_REPORTED))
                    .forEach(ipSeg -> deleteInfo.getDeleteData().getHouse().add(new House(bhi.getId(), null, ipSeg.getId())));
            });
        //获取未上报的用户删除数据
        final List<BaseCustomer> deleteBaseCustomerList = baseCustomerService.selectListForDelReport(new BaseCustomer().setIdcId(deleteBaseOperCompany.getIdcId()));
        deleteBaseCustomerList.stream()
            .filter(bc -> bc.getDataFeature() == DataFeatureConstant.DELETE && bc.getReportStatus() == ReportStatusConstant.NOT_REPORTED)
            .forEach(bc -> deleteInfo.getDeleteData().getUser().add(new User(bc.getId(), null, null)));
        deleteBaseCustomerList.stream()
            .filter(bc -> bc.getDataFeature() != DataFeatureConstant.DELETE)
            .forEach(bc -> {
                //删除的应用服务数据
                baseServiceInfoService.selectListForDelReport(new BaseServiceInfo().setCustomerId(bc.getId()))
                    .forEach(baseServiceInfo -> {
                        User user = new User(bc.getId(), null, null);
                        if (baseServiceInfo.getDataFeature() == DataFeatureConstant.DELETE && baseServiceInfo.getReportStatus() == ReportStatusConstant.REPORTING) {
                            com.zx.idc.xml.entity.basedata.delete.Service service = new com.zx.idc.xml.entity.basedata.delete.Service(baseServiceInfo.getId(), null, null);
                            user.getService().add(service);
                            deleteInfo.getDeleteData().getUser().add(user);
                        } else {
                            List<Long> domainIdList = baseServiceDomainService.selectListForDelReport(new BaseServiceDomain()
                                .setServiceId(baseServiceInfo.getId()).setDataFeature(DataFeatureConstant.DELETE).setReportStatus(ReportStatusConstant.NOT_REPORTED))
                                .stream().map(baseServiceDomain -> new Domain(baseServiceDomain.getId(), null).getId()).collect(Collectors.toList());
                            if (domainIdList.size() > 0) {
                                com.zx.idc.xml.entity.basedata.delete.Service service = new com.zx.idc.xml.entity.basedata.delete.Service(baseServiceInfo.getId(), domainIdList, null);
                                user.getService().add(service);
                                deleteInfo.getDeleteData().getUser().add(user);
                            }
                        }
                    });
                //删除的占用机房信息
                baseHousesHoldInfoService.selectListForDelReport(new BaseHousesHoldInfo().setCustomerId(bc.getId())
                    .setDataFeature(DataFeatureConstant.DELETE).setReportStatus(ReportStatusConstant.NOT_REPORTED))
                    .forEach(bhhi -> {
                        User user = new User(bc.getId(), null, bhhi.getId());
                        deleteInfo.getDeleteData().getUser().add(user);
                    });
            });
        //如果没有需要删除上报的数据，返回null，以便后续处理
        if (deleteInfo.getDeleteData().getHouse().size() == 0 && deleteInfo.getDeleteData().getUser().size() == 0) {
            return null;
        }
        return deleteInfo;
    }

    private UpdateInfo getUpdateInfo(BaseOperCompany updateBaseOperCompany) {
        final int notReported = ReportStatusConstant.NOT_REPORTED;
        // 网络信息安全责任人
        final BaseHouseOfficer updateSecurityOwner = updateBaseOperCompany.getSecurityOwner() != null ? baseHouseOfficerService.selectOne(new BaseHouseOfficer()
            .setId(updateBaseOperCompany.getSecurityOwner())) : null;
        // 应急联系人信息
        final BaseHouseOfficer updateEmergencyContact = updateBaseOperCompany.getEmergencyContact() != null ? baseHouseOfficerService.selectOne(new BaseHouseOfficer()
            .setId(updateBaseOperCompany.getEmergencyContact())) : null;
        //机房数据
        final List<BaseHouseInfo> updateBaseHouseInfoList = baseHouseInfoService.selectList(new BaseHouseInfo()
            .setIdcId(updateBaseOperCompany.getIdcId())
            .setReportStatus(notReported).setDataFeature(DataFeatureConstant.UPDATE)
        );
        //用户数据
        final List<BaseCustomer> updateBaseCustomerList = baseCustomerService.selectList(new BaseCustomer().setReportStatus(notReported).setDataFeature(DataFeatureConstant.UPDATE));
        //如果没有新增的上报数据，直接返回NULL
        if (updateBaseHouseInfoList.size() == 0 && updateBaseCustomerList.size() == 0) {
            return null;
        }
        //机房信息安全责任人
        final Map<Long, BaseHouseOfficer> baseHouseOfficerMap = baseIdcBasicDataService.queryBaseHouseOfficerMap(updateBaseHouseInfoList);
        //链路信息
        final List<BaseHouseLinkInfo> baseHouseLinkInfoList = baseIdcBasicDataService.queryBaseHouseLinkInfoList(updateBaseHouseInfoList);
        //ip 地址段信息
        final List<BaseIpAddressInfo> baseIpAddressInfoList = baseIdcBasicDataService.queryBaseIpAddressInfoList(updateBaseHouseInfoList);
        //所属机房区域
        final List<BaseIdcHouseArea> baseIdcHouseAreaList = baseIdcBasicDataService.queryBaseIdcHouseAreaList(updateBaseHouseInfoList);
        //机架信息
        final List<BaseFrameInfo> baseFrameInfoList = baseIdcBasicDataService.queryBaseFrameInfoList(baseIdcHouseAreaList);
        //提供互联网应用服务的信息
        //提供互联网应用服务的用户信息
        //人员信息
        final Map<Long, BaseHouseOfficer> baseCustomerHouseOfficerMap = baseIdcBasicDataService.queryBaseCustomerHouseOfficerMap(updateBaseCustomerList);
        //占用机房信息
        //服务信息
        final List<BaseServiceInfo> baseServiceInfoList = queryBaseServiceInfoList(updateBaseCustomerList);
        final Map<Long, List<BaseServiceDomain>> baseServiceDomainMap = baseServiceDomainService.listBatchByEntityList(
            baseServiceInfoList.stream()
                .map(bsi -> new BaseServiceDomain().setServiceId(bsi.getId()))
                .collect(Collectors.toList())
        )
            .stream()
            .collect(Collectors.groupingBy(BaseServiceDomain::getServiceId));
        //占用机房信息（含虚拟主机信息）
        final List<BaseHousesHoldInfo> baseHousesHoldInfoList = queryBaseHousesHoldInfoList(updateBaseCustomerList);
        //ip 地址转换信息
        final List<BaseIpTransInfo> baseIpTransInfoList = baseIdcBasicDataService.queryBaseIpTransInfoList(baseHousesHoldInfoList);
        //用户数据查询houseId需要的List
        final List<BaseHouseInfo> baseHouseInfoList = baseHouseInfoService.selectList(new BaseHouseInfo()
            .setIdcId(updateBaseOperCompany.getIdcId())
        );
        //用户数据需要 所属机房区域
        final List<BaseIdcHouseArea> idcHouseAreaList = baseIdcBasicDataService.queryBaseIdcHouseAreaList(baseHouseInfoList);
        //用户数据需要 机架信息
        final List<BaseFrameInfo> frameInfoList = baseIdcBasicDataService.queryBaseFrameInfoList(idcHouseAreaList);

        final UpdateInfo updateInfo = new UpdateInfo();
        updateInfo.setIdcId(updateBaseOperCompany.getIdcId());
        if (updateBaseOperCompany.getDataFeature() == DataFeatureConstant.UPDATE && updateBaseOperCompany.getReportStatus() == notReported) {
            updateInfo.setIdcName(updateBaseOperCompany.getOperName());
            updateInfo.setIdcAdd(updateBaseOperCompany.getAddress());
            updateInfo.setIdcZip(updateBaseOperCompany.getZipCode());
            updateInfo.setCorp(updateBaseOperCompany.getCompanyCorporation());
            if (updateSecurityOwner != null) {
                updateInfo.setIdcOfficer(new IdcOfficer(updateSecurityOwner.getName(), updateSecurityOwner.getIdType(), updateSecurityOwner.getId().toString(), updateSecurityOwner.getTel(), updateSecurityOwner.getMobile(), updateSecurityOwner.getEmail()));
            }
            if (updateEmergencyContact != null) {
                updateInfo.setEmergencyContact(new EmergencyContact(updateEmergencyContact.getName(), updateEmergencyContact.getIdType(), updateEmergencyContact.getId().toString(), updateEmergencyContact.getTel(), updateEmergencyContact.getMobile(), updateEmergencyContact.getEmail()));
            }
        }
        updateInfo.setUpdateData(new UpdateData());
        //机房数据
        if (updateBaseHouseInfoList.size() > 0) {
            updateInfo.getUpdateData().getHouseInfo().addAll(idcBasicDataUtil.getHouseInfoList(updateBaseHouseInfoList, baseHouseOfficerMap, baseHouseLinkInfoList, baseIpAddressInfoList, baseFrameInfoList));
        }
        //用户数据
        if (updateBaseCustomerList.size() > 0) {
            updateInfo.getUpdateData().getUserInfo().addAll(idcBasicDataUtil.getUserInfoList(idcHouseAreaList, frameInfoList, updateBaseCustomerList, baseCustomerHouseOfficerMap, baseServiceInfoList, baseServiceDomainMap, baseHousesHoldInfoList, baseIpTransInfoList));
        }
        return updateInfo;
       /* return new UpdateInfo(updateBaseOperCompany.getIdcId(), updateBaseOperCompany.getOperName(), updateBaseOperCompany.getAddress(), updateBaseOperCompany.getZipCode(), updateBaseOperCompany.getCompanyCorporation(), new IdcOfficer(updateSecurityOwner.getName(), updateSecurityOwner.getIdType(), updateSecurityOwner.getId().toString(), updateSecurityOwner.getTel(), updateSecurityOwner.getMobile(), updateSecurityOwner.getEmail()),
            new EmergencyContact(updateEmergencyContact.getName(), updateEmergencyContact.getIdType(), updateEmergencyContact.getId().toString(), updateEmergencyContact.getTel(), updateEmergencyContact.getMobile(), updateEmergencyContact.getEmail()),
            new UpdateData(
                //机房数据
                idcBasicDataUtil.getHouseInfoList(updateBaseHouseInfoList, baseHouseOfficerMap, baseHouseLinkInfoList, baseIpAddressInfoList, baseFrameInfoList),
                //用户数据
                idcBasicDataUtil.getUserInfoList(baseIdcHouseAreaList, baseFrameInfoList, updateBaseCustomerList, baseCustomerHouseOfficerMap, baseServiceInfoList, baseServiceDomainMap, baseHousesHoldInfoList, baseIpTransInfoList)
            )
        );*/


    }

    private List<BaseServerInfo> queryBaseServerInfoList(List<BaseCustomer> baseCustomerList) {
        return baseServerInfoService.listBatchByEntityList(baseCustomerList.stream()
            .map(bc -> new BaseServerInfo().setUseUser(bc.getId()))
            .collect(Collectors.toList()));
    }

    private List<BaseServiceInfo> queryBaseServiceInfoList(List<BaseCustomer> baseCustomerList) {
        return baseServiceInfoService.listBatchByEntityList(baseCustomerList.stream()
            .map(bc -> new BaseServiceInfo().setCustomerId(bc.getId()))
            .collect(Collectors.toList()));
    }

    private NewInfo getNewInfo(BaseOperCompany newBaseOperCompany) {
        final int notReported = ReportStatusConstant.NOT_REPORTED;
        // 网络信息安全责任人
        final BaseHouseOfficer newSecurityOwner = newBaseOperCompany.getSecurityOwner() != null ? baseHouseOfficerService.selectOne(new BaseHouseOfficer()
            .setId(newBaseOperCompany.getSecurityOwner())) : null;
        // 应急联系人信息
        final BaseHouseOfficer newEmergencyContact = newBaseOperCompany.getEmergencyContact() != null ? baseHouseOfficerService.selectOne(new BaseHouseOfficer()
            .setId(newBaseOperCompany.getEmergencyContact())) : null;
        //机房数据
        final List<BaseHouseInfo> newBaseHouseInfoList = baseHouseInfoService.selectList(new BaseHouseInfo()
            .setIdcId(newBaseOperCompany.getIdcId())
            .setReportStatus(notReported).setDataFeature(DataFeatureConstant.NEW)
        );
        //用户数据
        final List<BaseCustomer> newBaseCustomerList = baseCustomerService.selectList(new BaseCustomer()
            .setIdcId(newBaseOperCompany.getIdcId())
            .setReportStatus(notReported).setDataFeature(DataFeatureConstant.NEW));
        //如果没有新增的上报数据，直接返回NULL
        if ((newBaseOperCompany.getDataFeature() != DataFeatureConstant.NEW || newBaseOperCompany.getReportStatus() != ReportStatusConstant.NOT_REPORTED) && newBaseHouseInfoList.size() == 0 && newBaseCustomerList.size() == 0) {
            return null;
        }

        final NewInfo newInfo = new NewInfo();
        newInfo.setIdcId(newBaseOperCompany.getIdcId());
        if (newBaseOperCompany.getDataFeature() == DataFeatureConstant.NEW && newBaseOperCompany.getReportStatus() == notReported) {
            newInfo.setIdcName(newBaseOperCompany.getOperName());
            newInfo.setIdcAdd(newBaseOperCompany.getAddress());
            newInfo.setIdcZip(newBaseOperCompany.getZipCode());
            newInfo.setCorp(newBaseOperCompany.getCompanyCorporation());
            if (newSecurityOwner != null) {
                newInfo.setIdcOfficer(new IdcOfficer(newSecurityOwner.getName(), newSecurityOwner.getIdType(), newSecurityOwner.getId().toString(), newSecurityOwner.getTel(), newSecurityOwner.getMobile(), newSecurityOwner.getEmail()));
            }
            if (newEmergencyContact != null) {
                newInfo.setEmergencyContact(new EmergencyContact(newEmergencyContact.getName(), newEmergencyContact.getIdType(), newEmergencyContact.getId().toString(), newEmergencyContact.getTel(), newEmergencyContact.getMobile(), newEmergencyContact.getEmail()));
            }
        }
        //机房数据
        if (newBaseHouseInfoList.size() > 0) {
            //机房信息安全责任人
            final Map<Long, BaseHouseOfficer> baseHouseOfficerMap = baseIdcBasicDataService.queryBaseHouseOfficerMap(newBaseHouseInfoList);
            //链路信息
            final List<BaseHouseLinkInfo> baseHouseLinkInfoList = baseIdcBasicDataService.queryBaseHouseLinkInfoList(newBaseHouseInfoList);
            //ip 地址段信息
            final List<BaseIpAddressInfo> baseIpAddressInfoList = baseIdcBasicDataService.queryBaseIpAddressInfoList(newBaseHouseInfoList);
            //所属机房区域
            final List<BaseIdcHouseArea> baseIdcHouseAreaList = baseIdcBasicDataService.queryBaseIdcHouseAreaList(newBaseHouseInfoList);
            //机架信息
            final List<BaseFrameInfo> baseFrameInfoList = baseIdcBasicDataService.queryBaseFrameInfoList(baseIdcHouseAreaList);

            newInfo.getHouseInfo().addAll(idcBasicDataUtil.getHouseInfoList(newBaseHouseInfoList, baseHouseOfficerMap, baseHouseLinkInfoList, baseIpAddressInfoList, baseFrameInfoList));
//            newInfo.setHouseCount((long) newBaseHouseInfoList.size());
        }
        //用户数据
        if (newBaseCustomerList.size() > 0) {
            //提供互联网应用服务的信息
            //提供互联网应用服务的用户信息
            //人员信息
            final Map<Long, BaseHouseOfficer> baseCustomerHouseOfficerMap = baseIdcBasicDataService.queryBaseCustomerHouseOfficerMap(newBaseCustomerList);
            //服务信息
            final List<BaseServiceInfo> baseServiceInfoList = queryBaseServiceInfoList(newBaseCustomerList);
            final Map<Long, List<BaseServiceDomain>> baseServiceDomainMap = baseServiceDomainService.listBatchByEntityList(baseServiceInfoList.stream()
                .map(bsi -> new BaseServiceDomain().setServiceId(bsi.getId()))
                .collect(Collectors.toList())).stream().collect(Collectors.groupingBy(BaseServiceDomain::getServiceId));
            //占用机房信息（含虚拟主机信息）
            final List<BaseHousesHoldInfo> baseHousesHoldInfoList = queryBaseHousesHoldInfoList(newBaseCustomerList);
            //ip 地址转换信息
            final List<BaseIpTransInfo> baseIpTransInfoList = baseIdcBasicDataService.queryBaseIpTransInfoList(baseHousesHoldInfoList);

            //用户数据查询houseId需要的List
            final List<BaseHouseInfo> baseHouseInfoList = baseHouseInfoService.selectList(new BaseHouseInfo()
                .setIdcId(newBaseOperCompany.getIdcId())
            );
            //用户数据需要 所属机房区域
            final List<BaseIdcHouseArea> idcHouseAreaList = baseIdcBasicDataService.queryBaseIdcHouseAreaList(baseHouseInfoList);
            //用户数据需要 机架信息
            final List<BaseFrameInfo> frameInfoList = baseIdcBasicDataService.queryBaseFrameInfoList(idcHouseAreaList);

            newInfo.getUserInfo().addAll(idcBasicDataUtil.getUserInfoList(idcHouseAreaList, frameInfoList, newBaseCustomerList, baseCustomerHouseOfficerMap, baseServiceInfoList, baseServiceDomainMap, baseHousesHoldInfoList, baseIpTransInfoList));
        }
        return newInfo;
    }

    private List<BaseHousesHoldInfo> queryBaseHousesHoldInfoList(List<BaseCustomer> baseCustomerList) {
        return baseHousesHoldInfoService.listBatchByEntityList(baseCustomerList.stream()
            .map(bsi -> new BaseHousesHoldInfo().setCustomerId(bsi.getId()))
            .collect(Collectors.toList()));
    }
}
